#pragma once
#include <memory>
#include <mutex>
#include <map>
#include <condition_variable>
#include "source/Source.h"
#include "decoder/VDecoderManager.h"
#include "decoder/ADecoderManager.h"

namespace Media{
    class InputSource:public Source{
    public:
        using FrameConsumerId = uint32_t;
        using InputSourceId = uint32_t;
        using Ptr = std::shared_ptr<InputSource>; 
        InputSource(SourceInterfaceEnum iEnum, SourceMediaType mType, std::string content, bool isCustom);
        ~InputSource() override;
        bool Start();
        bool Stop();

        bool InputPacket(const FrameCommon::Frame::Ptr& frame);
        virtual FrameConsumerId AddVFrameConsumer(std::function<void (const AVFrame::Ptr)> framecb);
        virtual bool RemoveVFrameConsumer(FrameConsumerId id);

        FrameConsumerId AddAFrameConsumer(std::function<void (const AVFrame::Ptr)> framecb);
        bool RemoveAFrameConsumer(FrameConsumerId id);
    protected:
        virtual bool OpenSource() = 0;
        virtual bool CloseSource() = 0;
    private:
        bool createDecoder();
        bool destroyDecoder();

        std::map<FrameConsumerId, frameFuncCb> m_vframeConsumers;
        std::map<FrameConsumerId, frameFuncCb> m_aframeConsumers;

        VDecoder::Ptr m_vdecoder;
        ADecoder::Ptr m_adecoder;
        VDecoderManager::Ptr m_vmanager;
        ADecoderManager::Ptr m_amanager;
        std::recursive_mutex m_mux;
    };

}